//
//  OptionsModel.swift
//  Automobile
//
//  Created by erkebulan elzhan on 8/23/20.
//  Copyright © 2020 erkebulan elzhan. All rights reserved.
//

import Foundation

final class OptionsModel {
    
    public var sectionData: ([String], Int) = ([], 0)
    public var allRows: [[Any]] = []
    
    /// Loading Readable options from Server
    /// - Parameter completion: Reloading table view
    public func loadOptions (completion: @escaping (Bool) -> Void) {
        var request = URLRequest(url: URL(string: "http://advert.test.auto-nomad.kz:8000/api/cars/custom-options/readable/")!)
        request.allHTTPHeaderFields = ["Authorization": "93c2f6a8fe2e5b4cc05b49e99e93de55f57a8293"]
        let dataTask = URLSession.shared.dataTask(with: request) { (data, _, _) in
            
            guard let jsonData = data else {
                fatalError("fuck ur self")
            }
            
            DispatchQueue.main.async {
                do {
                    if let json = try JSONSerialization.jsonObject(with: jsonData, options: []) as? NSArray {
                        
                        var allData: [OptionSection] = []

                        for item in json {
                            let optionSection = OptionSection((item as! NSArray)[1] as! NSArray, name: (item as! NSArray)[0] as! String)
                            allData.append(optionSection)
                        }
                       
                        self.sectionData = (allData.map { $0.name }, allData.count)
                        
                        self.allRows = allData.map { (optionSection) -> [Any] in
                            return optionSection.single_fields + optionSection.choice_fields + optionSection.multiple_fields
                        }
                        completion(true)
                    }
                } catch let error as NSError {
                    print("Failed to load: \(error.localizedDescription)")
                }
            }
               
        }
        dataTask.resume()
    }
    
    
    /// Formatting options for creating car
    /// - Returns: { "daytime_running_lights": true, "fog_lights": true, "choice_fields": [ "headlights":1], "multiple_fields": ["key": 1,2,3] }"
    
    public func getResultOptions () -> [String:Any] {

        var results: [String: Any] = [:]

        for (_, container) in allRows.enumerated() {
            for row in container {
                if let singleItem = row as? SingleField {
                    if singleItem.isSelected {
                        results[singleItem.key] = true
                    }
                } else if let choiceItem = row as? ChoiceField {
                    if let index = choiceItem.fields.firstIndex(where: {
                        $0.id == choiceItem.selectedId
                    }) {
                        results[choiceItem.key] = choiceItem.fields[index].id
                    }
                } else if let multipleItem = row as? MultipleField {
                    if multipleItem.selectedItems.count != 0 {
                        results[multipleItem.key] = multipleItem.selectedItems
                    }
                }
            }
        }
        return results
    }
    
    /// Converting into string for filters
    /// - Returns: "electric_heating=1-2" for Multiple, "electric_heating"=1 for choice, "electric_heating" for single
    public func getFilterQuery () -> [String] {
        
        var singleResults: [String] = []
        var choiceResults: [String] = []
        var multipleResults: [String] = []
        
        for (_, container) in allRows.enumerated() {
            for row in container {
                if let singleItem = row as? SingleField {
                    if singleItem.isSelected {
                        singleResults.append(singleItem.key)
                    }
                } else if let choiceItem = row as? ChoiceField {
                    if let index = choiceItem.fields.firstIndex(where: {
                        $0.id == choiceItem.selectedId
                    }) {
                        choiceResults.append("\(choiceItem.key)=\(choiceItem.fields[index].id)")
                    }
                } else if let multipleItem = row as? MultipleField {
                    if multipleItem.selectedItems.count != 0 {
                        let result = multipleItem.selectedItems.map {"\($0)"}.joined(separator: "-")

                        multipleResults.append("\(multipleItem.key)=" + result)
                    }
                }
            }
        }
        
        return [singleResults.joined(separator: ","), choiceResults.joined(separator: ","), multipleResults.joined(separator: ",")]
    }
    
    
    // Converting filters to options
    
    public func importOptions (singleOptions: String, choiceOptions: String, multipleOptions: String) {
        
        let singleSelected = singleOptions.components(separatedBy: ",")
        
        let choiceItems = choiceOptions.components(separatedBy: ",")
        let choiceKeys = !choiceOptions.isEmpty ? choiceItems.map { $0.components(separatedBy: "=")[0] } : []
        let choiceValues = !choiceOptions.isEmpty ? choiceItems.map { $0.components(separatedBy: "=")[1] } : []
        
        let multipleItems = multipleOptions.components(separatedBy: ",")
        let multipleKeys = multipleOptions.isEmpty ? [] : multipleItems.map { $0.components(separatedBy: "=")[0] }
        let multipleValues = multipleOptions.isEmpty ? [] : multipleItems.map { $0.components(separatedBy: "=")[1] }
        
        for (rowId, container) in allRows.enumerated() {
            for (elId, row) in container.enumerated() {
                if let singleItem = row as? SingleField {
                    if singleSelected.contains(singleItem.key) {
                        var copy = (allRows[rowId][elId] as! SingleField)
                        copy.isSelected = true
                        allRows[rowId][elId] = copy
                    }
                } else if let choiceItem = row as? ChoiceField {
                    if let index = choiceKeys.firstIndex(of: choiceItem.key) {
                        var copy = allRows[rowId][elId] as! ChoiceField
                        copy.selectedId = Int(choiceValues[index])!
                        copy.isExpanded = true
                        allRows[rowId][elId] = copy
                    }
                } else if let multipleItem = row as? MultipleField {
                    if let index = multipleKeys.firstIndex(of: multipleItem.key) {
                        var copy = allRows[rowId][elId] as! MultipleField
                        copy.isExpanded = true
                        copy.selectedItems = multipleValues[index].components(separatedBy: "-").map {
                            Int($0)!
                        }
                        allRows[rowId][elId] = copy
                    }
                }
            }
        }
    }
    
    
    public func resetOptions (completion: (Bool) -> Void ) {
        for (rowId, container) in allRows.enumerated() {
            for (elId, row) in container.enumerated() {
                if let singleItem = row as? SingleField {
                    var copy = singleItem
                    copy.isSelected = false
                    allRows[rowId][elId] = copy
                } else if let choiceItem = row as? ChoiceField {
                    var copy = choiceItem
                    copy.selectedId = nil
                    copy.isExpanded = false
                    allRows[rowId][elId] = copy
                } else if let multipleItem = row as? MultipleField {
                    var copy = multipleItem
                    copy.selectedItems = []
                    copy.isExpanded = false
                    allRows[rowId][elId] = copy
                }
            }
        }
        completion(true)
    }
}
